#include <os/softirq.h>
#include <os/exception.h>
#include <os/debug.h>
#include <lib/type.h>

static softirq_action_t softirq_action[MAX_SOFTIRQ];
static uint64_t softirq_events;

// task assigt list head
LIST_HEAD(task_assigt_list_head);
LIST_HEAD(high_task_assigt_list_head);

void SoftIrqInit()
{
    softirq_events = 0;
    list_init(&task_assigt_list_head);
    list_init(&high_task_assigt_list_head);
    KPrint("[softirq] init softirq done.\n");
}

void SoftirqBuild(uint64_t softirq, softirq_action_t action)
{
    if (softirq >= 0 && softirq <= MAX_SOFTIRQ)
    {
        softirq_action[softirq] = action;
    }
    KPrint("[softirq] build irq\n");
}

void SoftirqActive(uint64_t softirq)
{
    if (softirq_action[softirq])
    {
        softirq_events |= (1 << softirq);
    }
    SoftIrqHandle();
}

static inline uint64_t SoftirqGetEvents()
{
    return softirq_events;
}

static inline void SoftirqSetEvents(uint64_t events)
{
    softirq_events = events;
}

__attribute__((optimize("O2"))) static inline void SoftirqDoHandle(uint64_t events);

static inline void SoftirqDoHandle(uint64_t events)
{
    softirq_action_t action;
    uint64_t i = 0;

    while (events)
    {
        action = softirq_action[i++];
        if (events & 0x01)
        {
            action();
        }
        events >>= 1;
    }
    // reset events to 0
    SoftirqSetEvents(0);
}

void SoftIrqHandle()
{
    uint64_t event;

    event = SoftirqGetEvents();
    // present softirq event do handle
    SoftirqDoHandle(event);
}
